#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
XML菜单/工具栏配置解析器
解析XML配置文件并构建Qt菜单和工具栏
"""

import os
from PyQt5.QtCore import Qt, QFile, QIODevice
from PyQt5.QtWidgets import QAction, QMenu, QToolBar, QComboBox
from PyQt5.QtGui import QIcon, QKeySequence
from xml.etree import ElementTree as ET

try:
    from .icon_manager import get_icon_manager
except ImportError:
    get_icon_manager = None


class MenuToolbarParser:
    """解析XML配置并构建菜单/工具栏"""
    
    def __init__(self, xml_path, action_registry=None, style_path=None, icon_manager=None):
        """
        初始化解析器
        
        Args:
            xml_path: XML配置文件路径
            action_registry: QAction注册表字典 {action_id: callable}
            style_path: QSS样式文件路径(可选)
            icon_manager: 图标管理器实例(可选)
        """
        self.xml_path = xml_path
        self.action_registry = action_registry or {}
        self.actions = {}  # 存储创建的QAction对象 {id: QAction}
        self.menus = {}    # 存储创建的QMenu对象
        self.toolbars = {} # 存储创建的QToolBar对象
        self.tree = None
        self.style_path = style_path or self._get_default_style_path()
        self.stylesheet = self._load_stylesheet()
        
        # 图标管理器
        if icon_manager:
            self.icon_manager = icon_manager
        elif get_icon_manager:
            self.icon_manager = get_icon_manager()
        else:
            self.icon_manager = None
        
    def _get_default_style_path(self):
        """获取默认样式文件路径"""
        xml_dir = os.path.dirname(os.path.abspath(self.xml_path))
        return os.path.join(xml_dir, 'toolbar_style.qss')
    
    def _load_stylesheet(self):
        """加载QSS样式表"""
        if not self.style_path or not os.path.exists(self.style_path):
            return ""
        
        try:
            with open(self.style_path, 'r', encoding='utf-8') as f:
                return f.read()
        except Exception as e:
            print(f"加载样式表失败: {e}")
            return ""
    
    def parse(self):
        """解析XML文件"""
        try:
            self.tree = ET.parse(self.xml_path)
            return True
        except Exception as e:
            print(f"解析XML失败: {e}")
            return False
    
    def _create_action(self, parent, element):
        """
        从XML元素创建QAction
        
        Args:
            parent: 父QObject
            element: XML元素
            
        Returns:
            QAction对象
        """
        action_id = element.get('id')
        text = element.get('text', '')
        icon_path = element.get('icon', '')
        shortcut = element.get('shortcut', '')
        tooltip = element.get('tooltip', '')
        checkable = element.get('checkable', 'false').lower() == 'true'
        checked = element.get('checked', 'false').lower() == 'true'
        
        # 创建QAction
        action = QAction(text, parent)
        
        # 保存图标名称（用于主题切换时重新加载）
        if icon_path:
            action._icon_name = icon_path  # 自定义属性
        
        # 设置图标(使用图标管理器)
        if icon_path:
            if self.icon_manager:
                # 使用图标管理器加载图标(支持动态着色)
                icon = self.icon_manager.get_icon(icon_path)
                action.setIcon(icon)
            else:
                # 回退到直接加载
                icon_full_path = os.path.join(
                    os.path.dirname(self.xml_path), 
                    'icons', 
                    f'{icon_path}.svg' if not icon_path.endswith('.svg') else icon_path
                )
                if os.path.exists(icon_full_path):
                    action.setIcon(QIcon(icon_full_path))
        
        # 设置快捷键
        if shortcut:
            action.setShortcut(QKeySequence(shortcut))
        
        # 设置提示
        if tooltip:
            action.setToolTip(tooltip)
            action.setStatusTip(tooltip)
        
        # 设置可选中属性
        if checkable:
            action.setCheckable(True)
            action.setChecked(checked)
        
        # 连接到注册的槽函数
        if action_id in self.action_registry:
            callback = self.action_registry[action_id]
            if checkable:
                action.toggled.connect(callback)
            else:
                action.triggered.connect(callback)
        
        # 保存action
        self.actions[action_id] = action
        
        return action
    
    def _build_menu(self, parent, menu_element):
        """
        递归构建菜单
        
        Args:
            parent: 父菜单或菜单栏
            menu_element: XML菜单元素
            
        Returns:
            QMenu对象
        """
        menu_id = menu_element.get('id')
        text = menu_element.get('text', '')
        icon_path = menu_element.get('icon', '')
        
        # 创建菜单
        menu = QMenu(text, parent)
        
        if icon_path:
            menu.setIcon(QIcon(icon_path))
        
        # 遍历子元素
        for child in menu_element:
            if child.tag == 'action':
                # 创建action并添加到菜单
                action = self._create_action(menu, child)
                menu.addAction(action)
                action.setCheckable(True)
                
            elif child.tag == 'separator':
                # 添加分隔符
                menu.addSeparator()
                
            elif child.tag == 'menu':
                # 递归创建子菜单
                submenu = self._build_menu(menu, child)
                menu.addMenu(submenu)
        
        # 保存菜单
        if menu_id:
            self.menus[menu_id] = menu
        
        return menu
    
    def build_menubar(self, menubar):
        """
        构建菜单栏
        
        Args:
            menubar: QMenuBar对象
        """
        if not self.tree:
            return
        
        root = self.tree.getroot()
        menubar_element = root.find('menubar')
        
        if menubar_element is None:
            return
        
        # 遍历所有菜单
        for menu_element in menubar_element.findall('menu'):
            menu = self._build_menu(menubar, menu_element)
            menubar.addMenu(menu)
    
    def build_toolbars(self, main_window):
        """
        构建工具栏
        
        Args:
            main_window: QMainWindow对象
            
        Returns:
            工具栏字典 {toolbar_id: QToolBar}
        """
        if not self.tree:
            return {}
        
        root = self.tree.getroot()
        toolbars_element = root.find('toolbars')
        
        if toolbars_element is None:
            return {}
        
        # 遍历所有工具栏
        first = True
        for toolbar_element in toolbars_element.findall('toolbar'):
            toolbar_id = toolbar_element.get('id')
            name = toolbar_element.get('name', '')
            area_str = toolbar_element.get('area', 'top')
            movable = toolbar_element.get('movable', 'true').lower() == 'true'
            
            # 转换区域字符串到Qt常量
            area_map = {
                'top': Qt.TopToolBarArea,
                'bottom': Qt.BottomToolBarArea,
                'left': Qt.LeftToolBarArea,
                'right': Qt.RightToolBarArea
            }
            area = area_map.get(area_str, Qt.TopToolBarArea)
            
            # 创建工具栏
            toolbar = QToolBar(name, main_window)
            toolbar.setMovable(movable)
            toolbar.setObjectName(toolbar_id)
            
            # 应用样式表
            if self.stylesheet:
                toolbar.setStyleSheet(self.stylesheet)
            
            # 添加到主窗口
            
            if first:
                first= False
            else:
                main_window.addToolBarBreak(Qt.TopToolBarArea)
            main_window.addToolBar(area, toolbar)
            
            # 遍历工具栏项
            for item in toolbar_element:
                if item.tag == 'action':
                    ref = item.get('ref')
                    if ref and ref in self.actions:
                        # 引用已存在的action
                        toolbar.addAction(self.actions[ref])
                    else:
                        # 创建新action
                        action = self._create_action(toolbar, item)
                        toolbar.addAction(action)
                        
                elif item.tag == 'separator':
                    toolbar.addSeparator()
                    
                elif item.tag == 'widget':
                    # 添加自定义控件
                    widget = self._create_toolbar_widget(toolbar, item)
                    if widget:
                        toolbar.addWidget(widget)
            
            # 保存工具栏
            self.toolbars[toolbar_id] = toolbar
        
        return self.toolbars
    
    def _create_toolbar_widget(self, parent, element):
        """
        创建工具栏自定义控件
        
        Args:
            parent: 父对象
            element: XML元素
            
        Returns:
            QWidget对象
        """
        widget_type = element.get('type')
        widget_id = element.get('id')
        tooltip = element.get('tooltip', '')
        
        widget = None
        
        if widget_type == 'combobox':
            widget = QComboBox(parent)
            widget.setObjectName(widget_id)
            
            # 添加选项
            for item in element.findall('item'):
                text = item.text or ''
                value = item.get('value', text)
                widget.addItem(text, value)
            
            if tooltip:
                widget.setToolTip(tooltip)
            
            # 注册到回调
            if widget_id in self.action_registry:
                callback = self.action_registry[widget_id]
                widget.currentIndexChanged.connect(callback)
        
        return widget
    
    def get_action(self, action_id):
        """获取已创建的action"""
        return self.actions.get(action_id)
    
    def get_menu(self, menu_id):
        """获取已创建的菜单"""
        return self.menus.get(menu_id)
    
    def get_toolbar(self, toolbar_id):
        """获取已创建的工具栏"""
        return self.toolbars.get(toolbar_id)
